import numpy as np
from sklearn.metrics.pairwise import euclidean_distances, cosine_similarity
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为黑体 	plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题

# 生成不同维度的数据
np.random.seed(42)


def generate_data(dimensions, num_points=1000):
    """
    生成指定维度的随机数据点
    """
    return np.random.rand(num_points, dimensions)


def calculate_pairwise_distances(data):
    """
    计算数据点之间的欧氏距离
    """
    distances = euclidean_distances(data, data)
    return distances


def analyze_data_distribution(dimensions_list, num_points=1000):
    """
    分析不同维度下数据点距离的分布特性
    """
    for dim in dimensions_list:
        data = generate_data(dim, num_points)
        distances = calculate_pairwise_distances(data)
        mean_distance = np.mean(distances)
        std_distance = np.std(distances)
        print(f"维度: {dim}, 平均距离: {mean_distance:.4f}, 距离标准差: {std_distance:.4f}")


# 分析不同维度下的稀疏性特征
dimensions_list = [2, 5, 10, 50, 100]
analyze_data_distribution(dimensions_list)

# 可视化低维数据分布
low_dim_data = generate_data(2, 200)
plt.scatter(low_dim_data[:, 0], low_dim_data[:, 1], alpha=0.6)
plt.title("2D Area")
plt.xlabel("X1")
plt.ylabel("X2")
plt.grid(True)
plt.show()


def generate_high_dim_data(dimensions, num_points=500):
    """生成指定维度的随机数据点"""
    return np.random.rand(num_points, dimensions)


def analyze_distance_metrics(dimensions_list, num_points=500):
    """分析不同维度下欧氏距离和余弦相似度的退化现象"""
    results = []
    for dim in dimensions_list:
        data = generate_high_dim_data(dim, num_points)
        eu_distances = euclidean_distances(data)
        cos_similarities = cosine_similarity(data)

        # 取非对角元素，避免自相似影响
        eu_dist_flat = eu_distances[np.triu_indices(num_points, k=1)]
        cos_sim_flat = cos_similarities[np.triu_indices(num_points, k=1)]

        results.append({
            'dimension': dim,
            'euclidean_mean': np.mean(eu_dist_flat),
            'euclidean_std': np.std(eu_dist_flat),
            'cosine_mean': np.mean(cos_sim_flat),
            'cosine_std': np.std(cos_sim_flat)
        })

    return results


# 分析维度从2到100的距离退化
dimensions_list = [2, 10, 20, 50, 100]
results = analyze_distance_metrics(dimensions_list)
# 打印分析结果
for res in results:
    print(
        f"维度: {res['dimension']}, 欧氏距离均值: {res['euclidean_mean']:.4f}, 欧氏距离标准差: {res['euclidean_std']:.4f}, "
        f"余弦相似度均值: {res['cosine_mean']:.4f}, 余弦相似度标准差: {res['cosine_std']:.4f}")
# 可视化结果
euclidean_means = [res['euclidean_mean'] for res in results]
cosine_means = [res['cosine_mean'] for res in results]
dimensions = [res['dimension'] for res in results]

plt.figure(figsize=(10, 5))
plt.plot(dimensions, euclidean_means, label='欧氏距离均值', marker='o')
plt.plot(dimensions, cosine_means, label='余弦相似度均值', marker='o')
plt.xlabel('维度')
plt.ylabel('度量值')
plt.title('不同维度下距离度量的退化')
plt.legend()
plt.grid(True)
plt.show()
